Chamado chegou — layout quebrado

Antes de abrir qualquer editor, leia o chamado. Em projetos reais, você precisa entender o problema antes de sair editando código.

Alta prioridade #4421 · Aberto há 2h

"O site da nossa loja tá com o layout dos cards de produto todo desconfigurado. O card ultrapassa o container cinza. Preciso de um fix urgente pra amanhã de manhã. Não mexa na estrutura HTML, só no CSS — o back-end já subiu o template em produção."

De: gerencia@lojaexemplo.com.br · Atribuído a: você

Restrição do cliente: você não pode alterar o HTML. A correção precisa ser feita apenas no CSS. Isso é extremamente comum em projetos reais.

O código que você recebeu

Abra a pasta exercicio/ no VS Code. Esses são os arquivos que estão no servidor. Tente visualizar o problema no navegador antes de continuar.

exercicio/index.html
<div class="container">
  <div class="product-card">
    <h2>Camiseta Básica</h2>
    <p class="price">R$ 49,90</p>
    <button>Comprar</button>
  </div>
</div>
exercicio/style.css
.container {
  width: 300px;
  background: #e8e8e8;
  border: 2px solid #ccc;
  padding: 0;
}

.product-card {
  width: 300px;         /* igual ao container */
  padding: 20px;         /* ← problema aqui */
  border: 3px solid #999; /* ← e aqui */
  background: white;
}
Sua missão antes de continuar: abra o arquivo no navegador. Observe que o card ultrapassa o container. Tente identificar por que isso acontece antes de ir para a próxima seção.

Abre o DevTools e investiga

Antes de qualquer fix, você precisa entender o que está acontecendo. DevTools é a ferramenta de diagnóstico de todo dev front-end.

  • 1 No navegador com o arquivo aberto, pressione F12 (ou clique com botão direito → Inspecionar)
  • 2 Clique no ícone de cursor e selecione o elemento .product-card
  • 3 Vá até a aba Computed ou role até o diagrama de Box Model no painel de estilos
  • 4 Anote os valores de border, padding e content que aparecem no diagrama
  • 5 Some tudo manualmente no papel antes de olhar a resposta abaixo
Cálculo para fazer no papel: com o comportamento padrão do CSS (content-box), o padding e o border são somados depois da largura declarada. Some tudo e veja qual é o tamanho real do card.
width: 300px + padding-L: 20px + padding-R: 20px + border-L: 3px + border-R: 3px = 346px no total
O container tem 300px. O card ocupa 346px. Ele é 46px maior do que o espaço disponível — por isso extravasa.

Como o Box Model funciona

Todo elemento HTML é uma caixa com 4 camadas. O problema é que o CSS, por padrão, não inclui padding e border no cálculo da largura — e aí o bug aparece.

margin
border
padding
content width × height

content-box (padrão)

width define só o conteúdo. Padding e border somam por fora. O elemento fica maior do que você declarou.

border-box (o que você quer)

width inclui tudo — padding e border já estão dentro do valor declarado. O elemento nunca vai além do tamanho definido.

Analogia: imagine que você pediu uma pizza de 30cm. Com content-box, a caixa embaixo não conta nos 30cm — a pizza "ocupa mais espaço". Com border-box, os 30cm já incluem a caixa e tudo mais.

Hora de consertar — sem alterar o HTML

O cliente não quer que você mexa na estrutura. A correção precisa ser só no CSS. Tente resolver antes de olhar a solução.

Seu desafio

O card precisa ter exatamente 300px de largura total, incluindo o padding de 20px e o border de 3px.

Adicione apenas uma propriedade CSS ao .product-card para resolver o problema. Não altere nada no HTML.

Abra exercicio/style.css e resolva antes de ver a solução abaixo
solução — exercicio/style.css
.product-card {
  width: 300px;
  padding: 20px;
  border: 3px solid #999;
  background: white;
  box-sizing: border-box; /* ← aqui está o fix */
}

Com border-box, o browser recalcula automaticamente o conteúdo:

total: 300px padding: 40px border: 6px = content: 254px
O elemento continua com 300px no total. O CSS se encarrega de encolher o content area automaticamente.

Mexa no código e observe o comportamento

Faça essas modificações no arquivo exercicio/style.css uma por vez. Salve e recarregue o navegador depois de cada alteração.

  • A Mude padding: 20px para padding: 50px sem o border-box. Observe o card explodir para fora.
  • B Adicione box-sizing: border-box e mantenha o padding em 50px. Veja o card se comportar corretamente dentro dos 300px.
  • C Mude o border para border: 15px solid red. Com border-box, o card continua em 300px. Sem ele, quanto fica?
  • D Remova o width: 300px do card e coloque width: 100%. O que acontece com e sem border-box?
  • Objetivo: você deve conseguir prever o comportamento antes de salvar. Se conseguir fazer isso, internalizou o Box Model de verdade.

    Novo pedido chegou

    O cliente ficou satisfeito com o fix e pediu uma melhoria: agora quer uma grade de 3 cards lado a lado dentro do container.

    Média prioridade #4422 · Novo

    "Agora quero 3 cards de produto lado a lado, dentro de um container de 900px. Cada card deve ter padding de 16px e border de 2px. Coloca um espaçamento de 15px entre eles. Os cards não podem ultrapassar o container."

    Restrições

    • 3 cards com largura igual, lado a lado em um container de 900px

    • Cada card: padding: 16px e border: 2px solid

    • Espaçamento de 15px entre cada card

    • Os cards não podem ultrapassar o container

    Não use Flexbox nem Grid — resolva com display: inline-block ou float
    dica de raciocínio — não é a solução completa
    /*
      Container: 900px
      3 cards + 2 gaps de 15px = 900px
      900 - 30 = 870px para os 3 cards
      870 / 3 = 290px por card
    
      Com border-box: width: 290px já inclui
      o padding de 16px e o border de 2px.
      Limpo, previsível, sem surpresa.
    */
    Calcule na mão antes de escrever o CSS. Em projeto real você vai precisar fazer esse cálculo de cabeça durante code review. Treinar agora economiza horas de debug depois.

    O que todo mundo faz de errado

    Esses erros aparecem em code review o tempo todo. Conhecer eles evita perder horas debugando o óbvio.

    Erro 1

    Esquecer que o padrão é content-box

    Você declara width: 300px, adiciona padding: 20px e se surpreende porque o elemento ficou com 340px. Não é bug do CSS — é o comportamento padrão. Solução definitiva: use border-box globalmente e esqueça esse problema para sempre.
    Erro 2

    Misturar % com padding sem border-box

    width: 50% + padding: 20px sem border-box resulta em um elemento maior que 50% do pai. O padding é somado por fora da porcentagem calculada. Com border-box, o padding fica dentro dos 50%.
    Erro 3

    Confundir margin com padding

    Padding cria espaçamento dentro do elemento (entre o conteúdo e a borda). Margin cria espaçamento fora do elemento (entre ele e o vizinho). Usar margin quando quer espaçamento interno é um erro clássico que muda completamente o resultado visual.
    Erro 4

    Margin collapse — margens verticais que somem

    Dois elementos empilhados com margin-bottom: 20px e margin-top: 20px não somam 40px — ficam 20px. Isso é o margin collapse: margens verticais adjacentes se colapsam para o maior valor. Só acontece no eixo vertical. Horizontal não colapsa.
    Erro 5

    Aplicar border-box só no elemento problemático

    Corrigir o bug em um elemento só e esquecer os outros. Alguns elementos funcionam, outros não. O comportamento vira inconsistente ao longo do projeto. A solução certa é aplicar globalmente com o seletor *.

    O reset que todo projeto real usa

    Não existe projeto sério de front-end sem esse reset. Ele vai no topo de todo arquivo CSS e previne 90% dos bugs de Box Model antes de escrever qualquer linha de código.

    style.css — primeira coisa do arquivo
    *,
    *::before,
    *::after {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    Por que ::before e ::after?

    Pseudo-elementos também são caixas. Sem incluir eles, ícones e decorações feitas com CSS puro podem ter comportamento diferente do esperado.

    Por que zerar margin e padding?

    Cada navegador tem estilos padrão diferentes. Resetar garante que o layout começa idêntico em todo lugar — Chrome, Firefox, Safari e Edge.

    Frameworks como Tailwind CSS e Bootstrap já incluem esse reset internamente. Se você usa CSS puro, adicione manualmente — é a primeira linha de qualquer projeto profissional.

    O que você aprendeu hoje

    Ticket #4421 resolvido. Aqui está o mapa do que foi coberto:

    Modelo padrão

    content-box

    padding e border somam por fora

    Modelo correto

    border-box

    padding e border ficam dentro

    Ferramenta

    DevTools

    diagrama de Box Model em Computed

    Reset global

    * { }

    aplique em todo projeto novo

    a regra de ouro
    /*
      content-box (padrão do CSS):
      tamanho real = width + padding + border
    
      border-box (o que você quer):
      tamanho real = width  ← só isso
    
      Sempre use border-box. Sempre.
    */
    Próximos passos: estude display: inline-block vs block e como o comportamento de margin muda em cada um. São os próximos bugs que você vai encontrar em projeto real.